# encoding: utf-8
"""
@Author: xiaxin
@ModuleName: relog_analysis
@Time: 2020/3/4 
@Desc:
"""

# access.log-20191117，通过正则表达式匹配，找出文件中所有访问记录里。访问次数最多的前10个IP，访问最频繁的前10个页面
# 60.191.66.222 - - [18/Nov/2019:03:46:17 +0800] "GET /manager/html HTTP/1.1" 502 575 "-" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)" "-"

import re


class LogAnalysis:
    """
    分析日志文件, 计算访问 TOP10 的ip 和 url
    """

    def __init__(self, logfile: str):
        self.logfile = logfile  # 处理日志的文件路径
        self.regex = re.compile("^(?P<ipaddress>([\d]+\.){3}[\d]+).*\"[\w]*(?P<url> /\S*).*")  # 正则分组
        self.ip_dict = {}  # ip数据字典
        self.url_dict = {}  # url数据字典

    # 排序
    def _sorted(self):
        with open(self.logfile, 'r') as f:
            # 迭代每行, 如果能匹配, 在相应的容器中插入值, 初始为 1
            for line in f:
                match_re = self.regex.match(line)
                if match_re:
                    ip = match_re.group('ipaddress')
                    url = match_re.group('url')
                    self.ip_dict[ip] = self.ip_dict.get(ip, 0) + 1
                    self.url_dict[url] = self.url_dict.get(url, 0) + 1

        # 字典解构, 组成二元组, sorted 函数key为元组中的第一个元素, 倒序
        return sorted(self.ip_dict.items(), key=lambda v: v[-1], reverse=True)[:10], sorted(self.url_dict.items(), key=lambda v: v[-1], reverse=True)[:10]

    # 打印
    def print_top(self):
        ip_top10, url_top10 = self._sorted()

        print(''.join(f'top{top+1}, ipaddress: {ip}, access count is {count}.\n' for top, (ip, count) in enumerate(ip_top10)))
        print(''.join(f'top{top+1}, url: {url}, access count is {count}.\n' for top, (url, count) in enumerate(url_top10)))


if __name__ == '__main__':
    ip = LogAnalysis('./access.log-20191119')
    ip.print_top()

# top1, ipaddress: 27.17.18.210, access count is 912.
# top2, ipaddress: 66.249.64.15, access count is 10.
# top3, ipaddress: 122.51.99.115, access count is 9.
# top4, ipaddress: 66.249.64.17, access count is 4.
# top5, ipaddress: 66.249.64.16, access count is 4.
# top6, ipaddress: 66.249.64.144, access count is 4.
# top7, ipaddress: 129.28.51.216, access count is 2.
# top8, ipaddress: 123.126.113.90, access count is 2.
# top9, ipaddress: 106.38.241.126, access count is 2.
# top10, ipaddress: 60.191.66.222, access count is 1.
#
# top1, url:  /, access count is 53.
# top2, url:  /test.php, access count is 11.
# top3, url:  /1.php, access count is 8.
# top4, url:  /robots.txt, access count is 6.
# top5, url:  /shell.php, access count is 6.
# top6, url:  /qq.php, access count is 6.
# top7, url:  /index.php, access count is 5.
# top8, url:  /x.php, access count is 5.
# top9, url:  /cmd.php, access count is 5.
# top10, url:  /manager/html, access count is 4.

# ip匹配不正确，漏了很多。url匹配对于一些特殊的情况，例如你的输出结果中/index.php这个url中，后面带参数的情况。
# 也是一个相同的页面，但是你的表达式没有匹配出来。尝试再修改一下代码。